package main

import (
	"fmt"
	"math"
)

const BitSize = 8

// 模拟一个8位的加法器
//全加器
type FullAdder struct {
	A  rune // 输入 1或0
	B  rune //输入 1或0
	Ci rune //输入（来自进位） 1或0
	S  rune //输出 1或0
	Co rune //输出（进位）1或0
}

// 8位加法器 包含8个全加器
type EightBitAdder struct {
	Adders []FullAdder
}

// 实例化一个加法器
func NewEightAdder() *EightBitAdder {
	adder := new(EightBitAdder)
	adder.Adders = make([]FullAdder, BitSize)
	for i := 0; i < BitSize; i++ {
		// 每个全加器的输入输出默认为0
		adder.Adders[i] = FullAdder{A: '0', B: '0', Ci: '0', S: '0', Co: '0'}
	}
	return adder
}

//二进制相加
func (adder *EightBitAdder) AddBit(a1, a2 string) string {

	s := make([]rune, BitSize)         //结果
	preCo := '0'                       //上一个全加器的进位 默认0
	for i = BitSize - 1; i >= 0; i-- { //从右往左遍历
		// 初始化全加器的输入值
		adder.Adders[i].A = rune(a1[i])
		adder.Adders[i].B = rune(a2[i])
		adder.Adders[i].Ci = preCo //上一个全加器的Co作为当前全加器的Ci
		adder.Adders[i].Add()      // 计算当前全加器
		preCo = adder.Adders[i].Co // 当前全加器的Co作为下一个全加器的C
		s[i] = adder.Adders[i].S   //记录当前全加器的结果
	}
	return string(s)

}

//计算单个全加器 根据A,B Ci计算S Co
func (fullAdder *FullAdder) Add() {

	if fullAdder.A == '1' && fullAdder.B == '1' { //两个输入都是1
		if fullAdder.Ci == '0' { //无进位
			fullAdder.S = '0'
		} else { //有进位
			fullAdder.S = '1'
		}
		fullAdder.Co = '1'
		return
	}
	if fullAdder.A == '0' && fullAdder.B == '0' { //两个输入都是0
		if fullAdder.Ci == '0' { //无进位
			fullAdder.S = '0'
		} else { //有进位
			fullAdder.S = '1'
		}
		fullAdder.Co = '0'
		return
	}
	// 两个输入1个位0 一个为1
	if fullAdder.Ci == '0' { //无进位
		fullAdder.S = '1'
		fullAdder.Co = '0'
	} else { //有进位
		fullAdder.S = '0'
		fullAdder.Co = '1'
	}
}

/**
二进制转10进制
*/
func BinaryToInt(s string) int {
	l := len(s)
	var sum = 0
	for i := 0; i < l; i++ {
		if s[i] == '1' {
			sum += int(math.Pow(float64(2), float64(l-1-i)))
		}
	}
	return sum
}

func main45() {
	a := "01001101" // 8位
	b := "00001100" // 8位
	adder := NewEightAdder()
	s := adder.AddBit(a, b)
	fmt.Println(s)
	fmt.Println(BinaryToInt(a))
	fmt.Println(BinaryToInt(b))
	fmt.Println(BinaryToInt(s))
}
